package cn.donting.plugin.spring.boot.starter;

import cn.donting.plugin.spring.boot.starter.exception.PluginLoadException;
import cn.donting.plugin.spring.boot.starter.utile.ClassUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;

/**
 *  JAR的插件加载器, 应该包括所有的运行类
 * @author donting
 *  2020-05-13 下午4:32
 */
@Slf4j
public class JarPluginLoader extends AbsPluginLoader {


    @Override
    public PluginWrapper load(File file) throws IOException, PluginLoadException {
        fileInspect(file);

        URLClassLoader classLoader = new PluginClassLoader(new URL[]{file.toURI().toURL()},Plugin.class.getClassLoader());

        PluginWrapper plugin = null;
        List<String> classesPackage = null;
        try {
            classesPackage = ClassUtil.getClassesPackage(file.getPath());
        } catch (IOException e) {
            log.error(e.getMessage(),e);
            throw e;
        }
        for (String s : classesPackage) {
            final Class<?> aClass;
            try {
                aClass = classLoader.loadClass(s);
                Plugin annotation = aClass.getAnnotation(Plugin.class);
                if (annotation != null) {
                    plugin = new PluginWrapper(file.getPath(), classLoader, annotation, aClass);
                    break;
                }
            } catch (ClassNotFoundException e) {
                log.warn(e.getMessage());
            } catch (NoClassDefFoundError e) {
                log.warn(e.getMessage());
            } catch (Exception e) {
                log.warn(e.getMessage(), e);
            }
        }
        if (plugin == null) {
            throw new PluginLoadException(file.getPath()+" is not plugin",file.getPath()+"不是一个插件");
        }
        return plugin;
    }

    @Override
    public boolean isApplicable(File file) {
        return true;
    }

}
